﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Data;

namespace Recipes.Transactions
{
    /// <summary>
    /// This scenario performs basic CRUD operations on a simple model without children.
    /// </summary>
    /// <typeparam name="TModel">A EmployeeClassification model or entity</typeparam>
    [TestCategory("Transactions")]
    public abstract class TransactionsTests<TEmployeeClassification> : TestBase
        where TEmployeeClassification : class, IEmployeeClassification, new()
    {
        protected abstract ITransactionsScenario<TEmployeeClassification> GetScenario();

        [TestMethod]
        public void CreateAndCommit()
        {
            var repository = GetScenario();

            var newRecord = new TEmployeeClassification();
            newRecord.EmployeeClassificationName = "Test " + DateTime.Now.Ticks;
            var newKey = repository.Create(newRecord, false);
            Assert.IsTrue(newKey >= 1000, "keys under 1000 were not generated by the database");

            var actual = repository.GetByKey(newKey);
            Assert.IsNotNull(actual);
            Assert.AreEqual(newKey, actual!.EmployeeClassificationKey);
            Assert.AreEqual(newRecord.EmployeeClassificationName, actual.EmployeeClassificationName);
        }

        [TestMethod]
        public void CreateAndRollback()
        {
            var repository = GetScenario();

            var newRecord = new TEmployeeClassification();
            newRecord.EmployeeClassificationName = "Test " + DateTime.Now.Ticks;
            var newKey = repository.Create(newRecord, true);
            Assert.IsTrue(newKey >= 1000, "keys under 1000 were not generated by the database");

            var actual = repository.GetByKey(newKey);
            Assert.IsNull(actual, "The record shouldn't exist because the transaction was rolled back");
        }

        [TestMethod]
        public void CreateAndCommitWithIsolationLevel()
        {
            var repository = GetScenario();

            var newRecord = new TEmployeeClassification();
            newRecord.EmployeeClassificationName = "Test " + DateTime.Now.Ticks;
            var newKey = repository.CreateWithIsolationLevel(newRecord, false, IsolationLevel.Serializable);
            Assert.IsTrue(newKey >= 1000, "keys under 1000 were not generated by the database");

            var actual = repository.GetByKey(newKey);
            Assert.IsNotNull(actual);
            Assert.AreEqual(newKey, actual!.EmployeeClassificationKey);
            Assert.AreEqual(newRecord.EmployeeClassificationName, actual.EmployeeClassificationName);
        }
    }
}
